

import java.io.Console;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.StringWriter;
import java.io.IOError;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.ArrayList;
import java.lang.NumberFormatException;

import VideoRent.*;
import VideoRent.Entrada.*;
import VideoRent.Salida.*;

public class VideoRent{

    private static final String opciones =
        "\nPor favor introduzca la opción que desea ejecutar" +
        "\n1. Introducir información de los artículos en existencia" +
        "\n2. Introducir clientes previamente asociados" +
        "\n3. Introducir acciones realizadas por clientes" +
        "\n4. Imprimir las acciones realizadas por los empleados y las acciones inválidas de los clientes" +
        "\n5. Imprimir las facturas" +
        "\n6. Imprimir artículos existentes" +
        "\n7. Imprimir información de los asociados" +
        "\n8. Imprimir artículos en préstamo" +
        "\n9. Salir";

    private static final String opcionErronea = "La opción que introdujo es inválida";

    private static final String introducirArchivo = "Introduzca la dirección al archivo que desea leer: ";

    private static BufferedWriter bufferEscrituraEmpleados;

    private static StringWriter escritorEmpleados;

    private static BufferedWriter bufferEscrituraFacturas;

    private static StringWriter escritorFacturas;

    private static Console consola;

    private static ElementosTienda elementosTienda;

    private static PrintWriter escritor;

    private static ArticulosExistencia articulosExistencia = null;

    private static ClientesAsociados clientesAsociados = null;

    private static AccionesCliente accionesCliente = null;

    private static ImprimirEmpleados imprimirEmpleados;

    private static ImprimirFacturas imprimirFacturas;

    private static ImprimirArticulosExistentes imprimirArticulosExistentes;

    private static ImprimirClientes imprimirClientes;

    private static ImprimirArticulosAlquilados imprimirArticulosAlquilados;

    public static void main(String[] argv){

        elementosTienda = ElementosTienda.getInstance();

        consola = System.console();
        if (null == consola){
            System.err.println("No se pudo obtener la cónsola");
            System.exit(1);
        }

        escritor = consola.writer();

        while (true){
            int opcion;
            escritor.println(opciones);
            escritor.flush();
            String entrada = leerLinea();
            try{
                opcion = Integer.parseInt(entrada);
            }catch(NumberFormatException e){
                escritor.println(opcionErronea);
                escritor.flush();
                continue;
            }
            if (9 == opcion){
                break;
            }
            try{
                switch (opcion){
                    case 1:
                        getArticulosExistencia().leer(getBufferLectura());
                        break;
                    case 2:
                        getClientesAsociados().leer(getBufferLectura());
                        break;
                    case 3:
                        getAccionesCliente().leer(getBufferLectura());
                        break;
                    case 4:
                        getBufferEscrituraEmpleados().flush();
                        getImprimirEmpleados().imprimir();
                        break;
                    case 5:
                        getBufferEscrituraFacturas().flush();
                        getImprimirFacturas().imprimir();
                        break;
                    case 6:
                        getImprimirArticulosExistentes().imprimir();
                        break;
                    case 7:
                        getImprimirClientes().imprimir();
                        break;
                    case 8:
                        getImprimirArticulosAlquilados().imprimir();
                        break;
                    case 9:
                        break;
                }
            }catch(Exception e){
                escritor.println("Hubo un error procesando la opción '" + opcion + "': " + e);
            }
        }
    }

    private static ArticulosExistencia getArticulosExistencia(){
        if (null == articulosExistencia){
            articulosExistencia = new ArticulosExistencia(elementosTienda);
        }
        return articulosExistencia;
    }

    private static ClientesAsociados getClientesAsociados(){
        if (null == clientesAsociados){
            clientesAsociados = new ClientesAsociados(elementosTienda);
        }
        return clientesAsociados;
    }

    private static AccionesCliente getAccionesCliente(){
        if (null == accionesCliente){
            accionesCliente = new AccionesCliente(elementosTienda, getBufferEscrituraEmpleados(), getBufferEscrituraFacturas());
        }
        return accionesCliente;
    }

    private static BufferedReader getBufferLectura(){

        FileReader lectorArchivo;

        while (true){
            escritor.print(introducirArchivo);
            escritor.flush();

            String nombreArchivo = leerLinea();

            try{
                lectorArchivo = new FileReader(nombreArchivo);
            }catch(FileNotFoundException e){
                escritor.println("El archivo '" + nombreArchivo + "' no existe.");
                continue;
            }

            break;
        }

        return new BufferedReader(lectorArchivo);
    }

    private static BufferedWriter getBufferEscrituraEmpleados(){
        if (null == bufferEscrituraEmpleados){
            bufferEscrituraEmpleados = new BufferedWriter(getEscritorEmpleados());
        }
        return bufferEscrituraEmpleados;
    }

    private static BufferedWriter getBufferEscrituraFacturas(){
        if (null == bufferEscrituraFacturas){
            bufferEscrituraFacturas = new BufferedWriter(getEscritorFacturas());
        }
        return bufferEscrituraFacturas;
    }

    private static StringWriter getEscritorEmpleados(){
        if (null == escritorEmpleados){
            escritorEmpleados = new StringWriter();
        }
        escritorEmpleados.flush();
        return escritorEmpleados;
    }

    private static StringWriter getEscritorFacturas(){
        if (null == escritorFacturas){
            escritorFacturas = new StringWriter();
        }
        escritorFacturas.flush();
        return escritorFacturas;
    }

    private static ImprimirEmpleados getImprimirEmpleados(){
        if (null == imprimirEmpleados){
            imprimirEmpleados = new ImprimirEmpleados(escritor, escritorEmpleados);
        }
        return imprimirEmpleados;
    }

    private static ImprimirFacturas getImprimirFacturas(){
        if (null == imprimirFacturas){
            imprimirFacturas = new ImprimirFacturas(escritor, escritorFacturas);
        }
        return imprimirFacturas;
    }

    private static ImprimirArticulosExistentes getImprimirArticulosExistentes(){
        if (null == imprimirArticulosExistentes){
            imprimirArticulosExistentes = new ImprimirArticulosExistentes(escritor, elementosTienda);
        }
        return imprimirArticulosExistentes;
    }

    private static ImprimirClientes getImprimirClientes(){
        if (null == imprimirClientes){
            imprimirClientes = new ImprimirClientes(escritor, elementosTienda);
        }
        return imprimirClientes;
    }

    private static ImprimirArticulosAlquilados getImprimirArticulosAlquilados(){
        if (null == imprimirArticulosAlquilados){
            imprimirArticulosAlquilados = new ImprimirArticulosAlquilados(escritor, elementosTienda);
        }
        return imprimirArticulosAlquilados;
    }

    private static String leerLinea(){
        while (true){
            try{
                return consola.readLine();
            }catch(IOError e){
                escritor.print("Hubo un error de lectura, por favor intente de nuevo: ");
            }
        }
    }
}